package com.equis.architecture.util{
	import mx.collections.ArrayCollection;
	import mx.collections.ArrayList;
	import mx.collections.IList;

	public class ListUtils {

        public static function difference(minuend:IList, subtrahend:IList):IList {
            var result:IList = clone(minuend);
            for each(var item:Object in subtrahend.toArray()) {
                var index:Number = result.getItemIndex(item);
                if (index != -1) {
                    result.removeItemAt(index);
                }
            }
            return result;

        }
		public static function clone(list:IList):IList {
			var copy:IList = new ArrayCollection();
            if (list == null) {
                return copy;
            }
            for each(var obj:Object in list.toArray()) {
				copy.addItem(obj);
			}
			return copy;
		}

		public static function addAll(list:IList, itemsToAdd:Object):IList {
			if(itemsToAdd is IList) {
				itemsToAdd = IList(itemsToAdd).toArray();
			}

			for each(var obj:Object in (itemsToAdd as Array)) {
				list.addItem(obj);
			}
			return list;

		}



		public static function isEmpty(list:IList):Boolean {
			return list == null || list.length < 1;
		}


		public static function remove(list:IList, bo:Object):void {
			var index:int = ListUtils.getIndexOf(list, bo);
			if(index >= 0) {
				list.removeItemAt(index);
			}
		}
		
		public static function removeAll(list:IList, itemsToRemove:Object):IList {
			if(itemsToRemove is IList) {
				itemsToRemove = IList(itemsToRemove).toArray();
			}

			for each(var obj:Object in (itemsToRemove as Array)) {
				remove(list, obj);
			}
			return list;
		}

		public static function contains(list:IList, obj:Object):Boolean {
			var index:int = ListUtils.getIndexOf(list, obj);
			return index >= 0;
		}

		public static function getIndexOf(list:IList, obj:Object):int {
			//TODO: ver si queremos comparar por igualdad como hacer.
			//¿Con el identity map (L1) lo necesitamos?
			return list.getItemIndex(obj);
		}

		public static function moveRight(list:IList, obj:Object):void {
			var index:int = list.getItemIndex(obj);
			if(index != list.length - 1) {
				list.removeItemAt(index);
				list.addItemAt(obj, index + 1);
			}
		}

		public static function moveLeft(list:IList, bo:Object):void {
			var index:int = list.getItemIndex(bo);
			if(index != 0) {
				list.removeItemAt(index);
				list.addItemAt(bo, index - 1);
			}
		}
		
		public static function subList(_list:IList, _from:int, _to:int):IList {
			var ret:IList = new ArrayList();
			for(var i:int = _from; i <= _to; ++i) {
				ret.addItem(_list.getItemAt(i));
			}
			return ret;
		}
		
		public static function sort(_list:IList, _comparator:Function):void {
			var array:Array = _list.toArray();
			array.sort(_comparator);
			
			for(var i:int = 0; i < _list.length; ++i) {
				if(_list.getItemAt(i) != array[i]) {
					_list.setItemAt(array[i], i);
				}
			}
		}
		
		public static function sigletonList(_item:Object):IList {
			var sl:IList = new ArrayList();
			sl.addItem(_item);
			return sl;
		}
	}
}